package com.hxz.graduationdesign.util;

import com.google.gson.*;
import com.hxz.graduationdesign.pojo.dto.CommentDto;
import com.hxz.graduationdesign.pojo.entity.ReplyComment;
import org.jsoup.Jsoup;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BilibiliCommentCrawler {

    // B站评论API
    private static final String COMMENT_API = "https://api.bilibili.com/x/v2/reply/main";
    private static final String REPLY_API = "https://api.bilibili.com/x/v2/reply/reply";

    // 用户代理
    private static final String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36";

    public static List<CommentDto> getVideoComments(String bvId, int maxPages, int maxReplyPages)
            throws IOException, InterruptedException {
        List<CommentDto> comments = new ArrayList<>();
        String aid = getAidFromBv(bvId);
        int next = 0;
        int page = 1;

        while (page <= maxPages) {
//            System.out.println("正在获取第 " + page + " 页顶级评论...");

            // 构建API请求URL
            String apiUrl = COMMENT_API + "?next=" + next + "&type=1&oid=" + aid + "&mode=3";

            try {
                String json = Jsoup.connect(apiUrl)
                        .ignoreContentType(true)
                        .userAgent(USER_AGENT)
                        .referrer("https://www.bilibili.com")
                        .timeout(10000)
                        .get()
                        .body()
                        .text();

                // 解析JSON
                JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
                JsonObject data = jsonObject.getAsJsonObject("data");

                // 获取评论
                JsonObject cursor = data.getAsJsonObject("cursor");
                JsonArray replies = data.getAsJsonArray("replies");

                if (replies != null) {
                    for (int i = 0; i < replies.size(); i++) {
                        JsonObject reply = replies.get(i).getAsJsonObject();
                        CommentDto comment = parseComment(reply);

                        // 回复
                        if (maxReplyPages > 0) {
//                            System.out.println("正在获取评论 " + comment.getId() + " 的回复...");
                            List<ReplyComment> commentReplies = getCommentReplies(aid, comment.getId(), maxReplyPages);
                            comment.setReplies(commentReplies);
                        }

                        comments.add(comment);
                    }
                }

                // 检查是否还有更多评论
                if (cursor != null && cursor.has("is_end") && !cursor.get("is_end").getAsBoolean()) {
                    next = cursor.get("next").getAsInt();
                    page++;

                    // 延迟，防止请求过快
                    Thread.sleep(2000);
                } else {
                    break;
                }
            } catch (Exception e) {
                System.err.println("获取第 " + page + " 页评论失败: " + e.getMessage());
                break;
            }
        }

        return comments;
    }

    private static List<ReplyComment> getCommentReplies(String aid, String rootRpid, int maxPages){
        List<ReplyComment> replies = new ArrayList<>();
        int page = 1;
        int next = 0;

        while (page <= maxPages) {
            String apiUrl = REPLY_API + "?pn=" + page + "&type=1&oid=" + aid +
                    "&ps=10&root=" + rootRpid + "&_=" + System.currentTimeMillis();

            try {
                String json = Jsoup.connect(apiUrl)
                        .ignoreContentType(true)
                        .userAgent(USER_AGENT)
                        .referrer("https://www.bilibili.com")
                        .timeout(8000)
                        .get()
                        .body()
                        .text();

                JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
                JsonObject data = jsonObject.getAsJsonObject("data");

                if (data != null) {
                    JsonArray replyReplies = data.getAsJsonArray("replies");

                    if (replyReplies != null) {
                        for (int i = 0; i < replyReplies.size(); i++) {
                            JsonObject reply = replyReplies.get(i).getAsJsonObject();
                            ReplyComment replyComment = parseReplyComment(reply, rootRpid);
                            replies.add(replyComment);
                        }
                    }

                    // 检查是否还有更多回复
                    JsonObject pageInfo = data.getAsJsonObject("page");
                    if (pageInfo != null && pageInfo.get("count").getAsInt() > page * 10) {
                        page++;
                        Thread.sleep(1000);
                    } else {
                        break;
                    }
                } else {
                    break;
                }
            } catch (Exception e) {
                System.err.println("获取评论 " + rootRpid + " 的第 " + page + " 页回复失败: " + e.getMessage());
                break;
            }
        }

        return replies;
    }

    private static CommentDto parseComment(JsonObject reply) {
        String rpid = reply.get("rpid").getAsString();
        JsonObject member = reply.getAsJsonObject("member");

        String user = member.get("uname").getAsString();
        String content = reply.get("content").getAsJsonObject().get("message").getAsString();
        int likeCount = reply.get("like").getAsInt();
        int level = member.get("level_info").getAsJsonObject().get("current_level").getAsInt();
        String gender = "未知";
        if (member.has("sex")) {
            gender = member.get("sex").getAsString();
        }

        return new CommentDto(rpid, user, content, likeCount, level, gender, new ArrayList<>());
    }

    private static ReplyComment parseReplyComment(JsonObject reply, String rootRpid) {
        String rpid = reply.get("rpid").getAsString();
        JsonObject member = reply.getAsJsonObject("member");

        String user = member.get("uname").getAsString();
        String content = reply.get("content").getAsJsonObject().get("message").getAsString();
        int likeCount = reply.get("like").getAsInt();
        int level = member.get("level_info").getAsJsonObject().get("current_level").getAsInt();
        String gender = "未知";
        if (member.has("sex")) {
            gender = member.get("sex").getAsString();
        }

//        String replyToUser = reply.get("parent_str").getAsString();

        return new ReplyComment(rpid, user, content, likeCount, level, gender, rootRpid);
    }

    private static String getAidFromBv(String bv) throws IOException {
        //获取AID
        String url = "https://www.bilibili.com/video/" + bv;

        String html = Jsoup.connect(url)
                .userAgent(USER_AGENT)
                .get()
                .html();

        Pattern pattern = Pattern.compile("\"aid\":(\\d+)");
        Matcher matcher = pattern.matcher(html);

        if (matcher.find()) {
            return matcher.group(1);
        } else {
            throw new IOException("无法从视频页面中提取AID");
        }
    }

    public static void printCommentInfo(List<CommentDto> comments) {
        for (CommentDto comment : comments) {
            System.out.println("【顶级评论】");
            System.out.println("用户: " + comment.getUsername() +
                    " Lv." + comment.getLevel() +
                    " 性别: " + comment.getGender());
            System.out.println("内容: " + comment.getContent());
            System.out.println("点赞: " + comment.getLikeCount());
            System.out.println("评论ID: " + comment.getId());

            if (!comment.getReplies().isEmpty()) {
                System.out.println("├─ 回复(" + comment.getReplies().size() + "条):");
                for (ReplyComment reply : comment.getReplies()) {
                    System.out.println("│  │  用户: " + reply.getUsername() +
                            " Lv." + reply.getLevel() +
                            " 性别: " + reply.getGender());
                    System.out.println("│  │  内容: " + reply.getContent());
                    System.out.println("│  │  点赞: " + reply.getLikeCount());
                    System.out.println("│  │  回复ID: " + reply.getId());
                }
            }
            System.out.println("────────────────────────");
        }
    }
}